#include "utils.h"
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>
#include "func_utils.h"
class Person{
  string name;
  int age;
  public:
  Person(string& n,int a):name(n),age(a){};
  string get_name(){return name;}
  int get_age(){return age;};
  int inc_age(int a){return age+a;}
  void info(){cout<<"name:"<<endl;}
};
int main() {
  using namespace std;
  vector<int> a = {1, 2, 3, 4, 5, 5};
  vector<int> b = {1, 3, 5};
  vector<int> c = {1, 3};
  cout << boolalpha << all_pos(a) << endl;
  cout << boolalpha << none_neg(a) << endl;
  cout << boolalpha << find_elem(a, 8) << endl;
  vector<int> d_a = double_elem(a);
  // vector<int>::iterator it = find_odd(a);
  // vector<int>::iterator it = find_first_elem(a,b);
  vector<int>::iterator it = find_two_elem(a);
  cout << num_count(a, 5) << endl;
  cout << even_num(a) << endl;

  auto elem = match_num(a, b);
  cout << *elem.first << " : " << *elem.second << endl;
  show_vec(d_a);
  cout << boolalpha << equal(a.begin(), a.end(), a.begin()) << endl;
  cout << boolalpha << is_permutation(a.begin(), a.end(), b.begin()) << endl;
  cout << *(search(b.begin(), b.end(), c.begin(), c.end())) << endl;
  cout << *(search_n(a.begin(), a.end(), 2, 5))
       << "\n"; // 在a中查找两个5出现的位置

  // auto iter = copy_vector(a, b);
  // copy_nelem(c, b, 2);
  mv_even(b, a);
  vector<int> t_a = {6,5,4,3,2,1};
  // swap(t_a,a);
  // iter_swap(t_a.begin(),t_a.end()-1);
  vector<int>tta = time_num(t_a, 2);
  replace(tta.begin(),tta.end(),10,20);
  replace_if(tta.begin(),tta.end(),[](int i){return i%2 == 0;},5);
  replace_copy(tta.begin(),tta.end(),tta.begin(),5,6);
  replace_copy_if(tta.begin(),tta.end(),tta.begin(),[](int i){return i==6;},7);
  vector<int> r = range(10);
  // remove(r.begin(),r.end(),7);
  // remove_if(r.begin(),r.end(),[](int i){return i%2==0;});
  vector<int> even_nums = vector<int>(5);
  // remove_copy_if(r.begin(),r.end(),even_nums.begin(),[](int i){return i%2==0;});//获取奇数元素存放在vector
  vector<int> union_num = vector<int>(a.size());
  unique_copy(a.begin(),a.end(),union_num.begin());
  reverse(union_num.begin(),union_num.end());
  vector<int> current_nums = range(10);
  vector<int> rotated_result = vector<int>(10);
  // rotate_copy(current_nums.begin(),current_nums.begin()+2,current_nums.end(),rotated_result.begin());
  partition(current_nums.begin(),current_nums.end(),[](int i){return i%2 == 0;});
  show_vec(current_nums);
  cout<<boolalpha<<is_partitioned(current_nums.begin(),current_nums.end(),[](int i){return i%2 == 0;});
  vector<int> stable_vector = range(10);
  stable_partition(stable_vector.begin(),stable_vector.end(),[](int i){return i%2 == 0;});
  vector<int> event = vector<int>(5);
  vector<int> odd = vector<int>(5);
  partition_copy(stable_vector.begin(),stable_vector.end(),event.begin(),odd.begin(),[](int t){return t%2 == 0;});
  
  show_vec(stable_vector);
  show_vec(event);
  show_vec(odd);

  vector<int> part_point = range(10);
  auto it_r = partition_point(part_point.begin(),part_point.end(),[](int i){return i%2==0;});
  vector<int> result;
  result.assign(part_point.begin(),it_r);


  vector<int> result1 = {4 ,3, 7, 8, 0, 5, 2, 1, 6, 9 };
  random_shuffle(result1.begin(),result1.end());
  partial_sort(result1.begin(),result1.begin()+5,result1.end());
  nth_element(result1.begin(),result.begin()+3,result1.end());
  sort(result1.begin(),result1.end());
  auto iter_low = lower_bound(result1.begin(),result1.end(),5);
  auto iter_upper = upper_bound(result1.begin(),result1.end(),5);
  cout<<"lower "<<*iter_low<<" upper:"<<*iter_upper<<"\n";

  pair<vector<int>::iterator,vector<int>::iterator> bounds;
  bounds = equal_range(result1.begin(),result1.end(),5);
  for(auto ir = result1.begin();ir<bounds.first;ir++)
  cout<<*ir<<" ";
  cout<<"\n";
  for(auto ir = bounds.second;ir<result1.end();ir++)
  cout<<*ir<<" ";
  cout<<"Left bound:"<<bounds.first-result1.begin()<<" right bound:"<<result1.end()-bounds.second<<"\n";

  vector<string> comp1 = {"one","two","three","four"};
  vector<string> comp2 = {"one","zero","four"};
  auto it_comp = lexicographical_compare(comp1.begin(),comp1.end(),comp2.begin(),comp2.end());
  cout<<boolalpha<<it_comp<<endl;
  
  auto f = bind(num_div,std::placeholders::_1,2);
  cout<<f(10)<<endl;
  string name = "liushuai";
  Person p = Person(name,30);
  auto inc2 = mem_fn(&Person::info());
  inc2();

  show_vec(result1);
}
